# -*- coding: utf-8 -*-

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import json
import time
import ssl
import os
import os.path
import base64
import binascii
import traceback
from tornado.concurrent import run_on_executor
# 这个并发库在python3自带;在python2需要安装sudo pip install futures
from concurrent.futures import ThreadPoolExecutor
from unpack import UnPackData

class BaseHandler(tornado.web.RequestHandler):

    @property
    def recv_data(self):
        param = self.request.body.decode('utf-8')
        return param

class MainHandler(BaseHandler):
    def get(self):
        self.write("go go weclouds!!!")

class deviceDataChangedHandler(BaseHandler):
    executor = ThreadPoolExecutor(10)
    def initialize(self, factory):
        self.factory = factory

    @tornado.gen.coroutine
    def post(self):
        rcvdata = self.recv_data
        yield self.block_task(rcvdata)

    @run_on_executor
    def block_task(self, rcvdata):
        try:
            print(str(rcvdata))
            result, decode_json = UnPackData.get_json_format(rcvdata)
            if result == False:
                return

            print(str(decode_json))
            if decode_json.has_key('notifyType') \
                    and decode_json.has_key('service') \
                    and decode_json['notifyType'] == "commandRsp":

                service_json = decode_json['service']
                if service_json.has_key('data'):
                    datamsg = service_json['data']

                    data = base64.b64decode(datamsg['rawData'])
                    if self.factory != None:
                        self.factory.print_string2hex(data)
                        self.factory.recvDataQ.put(data)
        except Exception, e:
            print(traceback.format_exc())
            print("commandRspHandler post error: %s" % str(e))

class commandRspHandler(BaseHandler):
    executor = ThreadPoolExecutor(2)
    def initialize(self, factory):
        self.factory = factory

    @tornado.gen.coroutine
    def post(self):
        rcvdata = self.recv_data
        yield self.block_task(rcvdata)

    @run_on_executor
    def block_task(self, rcvdata):
        try:
            print(str(rcvdata))
            result, decode_json = UnPackData.get_json_format(rcvdata)
            if result == False:
                return

            print(str(decode_json))
            if decode_json.has_key('notifyType') \
                    and decode_json.has_key('service') \
                    and decode_json['notifyType'] == "commandRsp":

                service_json = decode_json['service']
                if service_json.has_key('data'):
                    datamsg = service_json['data']

                    data = base64.b64decode(datamsg['rawData'])
                    if self.factory != None:
                        self.factory.print_string2hex(data)
                        self.factory.commandRespQ.put(data)
        except Exception, e:
            print(traceback.format_exc())
            print("commandRspHandler post error: %s" % str(e))

class Application(tornado.web.Application):
    def __init__(self, factory):
        handlers = [
        (r"/", MainHandler),
        (r"/rest/deviceDataChanged/subscriber", deviceDataChangedHandler,  {"factory": factory}),
        (r"/rest/commandRsp/subscriber", commandRspHandler,  {"factory": factory}),
        ]
        settings = dict(

        )
        tornado.web.Application.__init__(self, handlers, **settings)

def create_ssl_context(certfile, keyfile):
    ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)

    ssl_context.load_cert_chain(os.path.join(".", certfile), os.path.join(".", keyfile))
    return ssl_context

class NBIot_RestfulClass(object):
    def __init__(self, recvDataQ = None, commandRespQ  = None):
        self.recvDataQ = recvDataQ
        self.commandRespQ = commandRespQ
        application = Application(self)

        ssl_context = create_ssl_context("cert/server.crt", "cert/server.key")
        http_server = tornado.httpserver.HTTPServer(application, ssl_options=ssl_context)
        http_server.listen(8080)
        tornado.ioloop.IOLoop.instance().start()


    def print_string2hex(self, stringData):
        try:
            send_data = ""
            for k, count in enumerate(stringData):
                hexstr = binascii.b2a_hex(count)
                send_data = "%s%s"%(send_data,hexstr)
            print("Data %s" % (send_data))
        except Exception,e:
            print("print_string2hex error: %s"% str(e))

    def NBIot_server_stop(self):
        tornado.ioloop.IOLoop.instance().stop()

def start_nbiot_monitor(recvDataQ, commandRespQ):

    print("start restful server!")

    NBIot_RestfulClass(recvDataQ, commandRespQ)




if __name__ == "__main__":
    start_nbiot_monitor(None, None)
    print("exit restful server!")
